import serverConf from '@/config'
import { create } from '@prequest/miniprogram'
import QueryString from 'qs'
import type { PQRequest, PQResponse } from '@prequest/types'
import InterceptorMiddleware from '@prequest/interceptor'
import InterceptorActionHandler from './interceptorActionHandler'
import createCacheAdapter from '@prequest/cache'
import { headersHandler } from './handler/headers-handler'
import { cacheHandler } from './handler/cache-handler'
import { cancelTokenHandler } from './handler/cancel-token-handler'
import { paramsHandler } from './handler/params-handler'
import { errorHandler } from './handler/error-handler'
import { dataHandler } from './handler/data-handler'
import type { HttpInstance } from './types'
import { getToken } from './login'
import { appInit } from './appInit'

const cache = createCacheAdapter({
  getCacheKey: opt => {
    let queryStr = ''
    if (opt.data) queryStr = QueryString.stringify(opt.data)
    return opt.path + queryStr
  },
  // verifyRequest: opt => !opt.method || opt.method === 'GET',
})

const http: HttpInstance = create(uni.request, {
  baseURL: serverConf.api,
}, cache) as any


// 初始化token
http.use(async (ctx, next) => {
  await getToken()
  await next()
})

// 基本接口初始化
http.use(async (ctx, next) => {
  await appInit()
  await next()
})

const interceptor = new InterceptorMiddleware()

// 请求拦截器
const requestInterceptor = (request: PQRequest) => {
  const interceptorActionHandler = new InterceptorActionHandler()
  interceptorActionHandler
    .add(headersHandler)
    .add(cacheHandler())
    .add(cancelTokenHandler)
    .add(paramsHandler)
  return interceptorActionHandler.handleByAllAction(request)
}

// 响应拦截器
const responseInterceptor = (response: PQResponse) => {
  const interceptorActionHandler = new InterceptorActionHandler()
  interceptorActionHandler
    .add(errorHandler)
    .add(dataHandler)
  return interceptorActionHandler.handleByAllAction(response)
}

interceptor.request.use(requestInterceptor, error => { throw error })
interceptor.response.use(responseInterceptor, error => { throw error })
http.use(interceptor.run)

export default http
